#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<netinet/in.h>
#include<signal.h>

#define MAXLINE 4096
#define MAX_EVENTS 128
#define SET_EPOLL

char buf[4096];

struct get_pkg{
		int len;
		char* content;
};

void sig_child(int signo)
{
	pid_t pid;
	int stat;

	pid = wait(&stat);
	printf("child %d terminated\n", pid);
	return ;
}

void str_handle(int fd, const char* buf, int n)
{
	int show_buf_size = n - 3;
	char* show_buf = (char*)malloc(show_buf_size);
	memset(show_buf, 0, show_buf_size);
	memcpy(show_buf, buf + 4, show_buf_size - 1);
	show_buf[show_buf_size] = '\0';
	printf("get msg from client: %s", show_buf);
	free(show_buf);
}

void events_handle(int connfd)
{
	int n;
	for(;;) {
		if((n = read(connfd, buf, MAXLINE)) == 0){
					printf("recv error\n");
					break;
				} else {
					str_handle(connfd, buf, n);
				}
	}
}

void conn_handle(int fd)
{	
	int connfd;
	struct get_pkg *pkg;
	pid_t childpid;
	int i, n;
	
	for(;;){
			if((connfd = accept(fd, NULL, NULL)) == -1) {
					printf("accept socket error\n");
					continue;
			}
			//EINTR错误表示阻塞的时候被信号打断了
			if(errno == EINTR)
					continue;
			else {
					printf("accept error");
					exit(0);
			}
			if((childpid = fork()) == 0) {			
					close(fd);
					events_handle(connfd);
					exit(0);
			}
			close(connfd);
	}
}


int main(int argc, char **argv)
{	
	int listenfd;
	pid_t childpid;
	struct sockaddr_in servaddr;

	if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
			printf("creat socket error\n");
			exit(0);
	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(6666);

	if(bind(listenfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) == -1) {
			printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
			exit(0);
	}

//允许环境变量LISTENQ覆盖调用者指定的值。
	int backlog = atoi("LISTENQ");
	char *ptr;
	if((ptr = getenv("LISTENQ")) != NULL)
			backlog = atoi(ptr);

	printf("--------------------initlization success------------------");
	if(listen(listenfd, 10) == -1){
			printf("listen socket error\n");
			exit(0);
	}
	signal(SIGCHLD, sig_child);//子进程状态发生改变触发
	
	conn_handle(listenfd);
	
	return 0;
}
